#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> 
#define getjcb(type) (type*)malloc(sizeof(type)) 
#define NULL 0 

int n = 0, time = 0; float eti, ewi;

struct jcb {
	char name[10];           /* 作业名 */
	char state;              /* 作业状态 */
	int ts;                  /* 提交时间 */
	int tb;                  /* 开始运行时间 */
	int tc;                  /* 完成时间 */
	float ti;                /* 周转时间 */
	float wi;                /* 带权周转时间 */
	int ntime;               /* 作业所需运行时间 */
	int priority;            /* 优先级 */
	struct jcb* link;        /* 结构体指针 */
} *p, * q, * head = NULL;
typedef struct jcb JCB;

initial() 
{
	int i;
	printf("\nInput jcb num\n");
	scanf("%d", &n);
	printf("Input\nname\tts\tntime\tpriority\n");
	for (i = 0; i < n; i++) 
	{
		p = getjcb(JCB);
		scanf("%s\t%d\t%d\t%d", &p->name, &p->ts, &p->ntime, &p->priority);
		p->state = 'W';
		p->link = NULL;
		if (head == NULL) head = q = p;
		else 
		{
			q->link = p;
			q = p;
		}
	}
}




void print(JCB* pr) {
	JCB* p;
	printf("\ntime=%d", time);


	printf("\nname\tstate\tts\tntime\priority\ttb\ttc\tti\twi\n");
	printf("%s\t%c\t%d\t%d\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
		pr->name, pr->state, pr->ts, pr->ntime, pr->priority, pr->tb, pr->tc, pr->ti, pr->wi);

	p = head;
	do {
		if (p->state == 'W')

			printf("%s\t%c\t%d\t%d\t%d\n",
				p->name, p->state, p->ts, p->ntime, p->priority);

		p = p->link;
	} while (p != NULL);
	p = head;
	do {
		if (p->state == 'F')

			printf("%s\t%c\t%d\t%d\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
				p->name, p->state, p->ts, p->ntime, p->priority, p->tb, p->tc, p->ti, p->wi);
		p = p->link;
	} while (p != NULL);
}

void last() {
	eti /= n; ewi /= n;
	printf("\neti=%7.3f\tewi=%7.3f\n", eti, ewi);
}

void sjf() {
	JCB* min;
	int i, iden;
	for (i = 0; i < n; i++) {
		p = min = head; iden = 1;
		do {
			if (p->state == 'W' && p->ts <= time)
				if (iden) {
					min = p; iden = 0;
				}
				else if (p->ntime < min->ntime) min = p;
			p = p->link;
		} while (p != NULL);
		if (iden) {
			i--; printf("\ntime=%d:\tno JCB submib...wait...", time); time++;
			if (time > 100) { printf("\nruntime is too long...error"); getch(); }
		}
		else {
			running(min);
		}
	}
}

fcfs() {
	JCB* min;
	int i, iden;
	for (i = 0; i < n; i++) {
		p = min = head; iden = 1;
		do {
			if (p->state == 'W' && p->ts <= time)
				if (iden) {
					min = p; iden = 0;
				}
				else if (p->ts < min->ts) min = p;
			p = p->link;
		} while (p != NULL);

		if (iden) {
			i--; printf("\ntime=%d:\tno JCB submib...wait...", time); time++;
			if (time > 100) { printf("\nruntime is too long...error"); getch(); }
		}
		else {
			running(min);
		}
	}
}

running(JCB* p) {
	p->tb = time; p->state = 'R';
	p->tc = p->tb + p->ntime;
	p->ti = (float)(p->tc - p->ts);
	p->wi = (float)(p->ti / p->ntime);
	eti += p->ti;
	ewi += p->wi;
	print(p);
	time += p->ntime;
	p->state = 'F';
	printf("\n%s has been finished!\npress any key to continue...\n", p->name);
	getch();

}

void runjcb(int m) {

	printf("\n\nstart running jcb use algorithm %d.", m);
	switch (m) {
	case 1:fcfs(); break;
	case 2:sjf(); break;
	default:printf("\nrunjcb error...\n");
		exit(0);
	}
}


start() {
	int m;
	char str[100] = "\nselect algorithm\n1.FCFS\n2.SJF\n";
	printf("%s", str);
	m = getch() - 48;

	initial();
	if (1 <= m && m <= 2) runjcb(m);
	else {
		printf("\nselect error!try again...\n");
		start();
	}
	last();

}
main() {
	start();
	printf("\nfinished!");
	getch();
}